package io.bdmc.core.eu;

import io.bdmc.common.utils.ByteUtil;
import io.bdmc.common.utils.Constant;
import io.bdmc.core.msp2000.DataBuild;
import io.bdmc.core.msp2000.DataParse;
import io.bdmc.core.msp2000.Msp2000AlarmProcess;
import io.bdmc.core.msp2000.model.ElectronicTags;
import io.bdmc.core.msp2000.model.Msp2000Ter2Platform;
import io.bdmc.core.udp.UdpClientSendData;
import io.bdmc.modules.bss.entity.DeviceDevice;
import io.bdmc.modules.bss.entity.DeviceMachineEdfa;
import io.bdmc.modules.bss.entity.DeviceMachineFec;
import io.bdmc.modules.bss.entity.DeviceMachineRt;
import io.bdmc.modules.bss.model.DiskTypeEnum;
import io.bdmc.modules.bss.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Component
public class EUDeviceDataSync {

    @Autowired
    EUDataRead euDataRead;

    @Autowired
    IDeviceDeviceService _devSvs;

    @Autowired
    UdpClientSendData _udpClient;

    @Autowired
    IDeviceMachineFspService _fspService;

    @Autowired
    IDeviceMachineEdfaService _edfaService;

    @Autowired
    IDeviceMachineRtService _rtService;

    @Autowired
    IDeviceMachineFecService _fecService;

    @Autowired
    IDeviceMachineFecModuleService _fecModuleService;

    @Autowired
    IDeviceMachineRfaService _rfaService;

    @Autowired
    Msp2000AlarmProcess _msp2000AlarmProcess;

    /**
     * 自动拉取1u的nms设备数据
     */
    @Scheduled(cron = "0/10 * * * * ? ")
    public void autoFetchNMSDataRead() {
        final List<DeviceDevice> nmsList = _devSvs.getByDigestAndType( Constant.EU, Constant.NMS);
        try {
            for (DeviceDevice nms : nmsList) {
                //读nms信息
                getNMSInfo(nms);
                //读nms下面设备数据
                getNMSDeviceSon(nms);
            }
        } catch (Exception ex) {
            log.error(ex.getMessage());
        }
    }

    /**
     * 自动拉取1u-4u直连设备数据
     */
    @Scheduled(fixedDelay = 1000 * 10)
    public void auto1UDeviceDataRead() {
        //读取直连设备，包含1u和4u
        final List<DeviceDevice> directDeviceList = _devSvs.getDirectConnDevice();
        try {
            for (DeviceDevice dev : directDeviceList) {
                if (StringUtils.isEmpty(dev.getIpaddr())) {
                    continue;
                }
                switch (dev.getDeviceType()) {
                    case "FEC-10G":
                        // String sendMsg = DataBuild.build0401Msg();
                        euDataRead.sendFec1U(dev);
                        break;
                    case "BA":
                        euDataRead.sendEDFA1U(dev);
                        break;
                    case "PA": {
                        euDataRead.sendEDFA1U(dev);
                        break;
                    }
                    case "RTBA": {
                        euDataRead.sendRT1U(dev);
                        break;
                    }case "4U": {
                        euDataRead.sendFSPFU(dev);
                        break;
                    }
                }
            }
        } catch (Exception ex) {
            log.error(ex.getMessage());
        }
    }


    private void getNMSInfo(DeviceDevice nms) {
        String pollCmd = DataBuild.buildFF01Msg();
        String parseData = _udpClient.sendPollCommand(nms.getIpaddr(), nms.getDevicePort(), pollCmd);
        // System.out.println(parseData);
        Msp2000Ter2Platform msg = DataParse.parseAllMsg(ByteUtil.hexToBytes(parseData));
        if (msg.getComm().equals("FF01")) {
            String data = msg.getData();
            if (data.startsWith("6E9E")) {
                ElectronicTags e = DataParse.parse1uElectronicTags(data);
                final String sn = e.getEtegInfo().getSn();
                if (io.bdmc.common.utils.StringUtils.isEmpty(nms.getDeviceSn())) {
                    nms.setDeviceSn(sn);
                    nms.updateById();
                }
                System.out.println("1U电子标签");
            }
        }
    }

    /**
     * 获取nms下的所有设备
     *
     * @param nms nms设备
     */
    private void getNMSDeviceSon(DeviceDevice nms) {
        String pollCmd = DataBuild.build0401Msg();
        String receiveMsg = _udpClient.sendPollCommand(nms.getIpaddr(), nms.getDevicePort(), pollCmd);
        Msp2000Ter2Platform msg = DataParse.parseAllMsg(ByteUtil.hexToBytes(receiveMsg));
        if (msg.getComm().equals("0401")) {
            String data = msg.getData();
            // String sn = data.substring(0,8);
            int baCount = ByteUtil.HexToInt(data, 8, 2);
            int paCount = ByteUtil.HexToInt(data, 10, 2);
            int rtCount = ByteUtil.HexToInt(data, 14, 2);
            int fecCount = ByteUtil.HexToInt(data, 16, 2);
            data = data.substring(24 + 4);
            for (int i = 0; i < baCount; i++) {
                DeviceMachineEdfa ba = DataParse.parseDevice1UBA(data);
                final DeviceDevice baDevice = insertOrUpdateNMSSon(ba.getDiskSn(), DiskTypeEnum.EDFA.name(), nms);
                final DeviceDevice deviceDevice = _devSvs.getDeviceBySn(ba.getDiskSn());
                ba.setDeviceId(deviceDevice.getDeviceId());
                _edfaService.save(ba);
                _msp2000AlarmProcess.edfaAlarm(ba, baDevice);
                data = data.substring(120);
            }
            for (int i = 0; i < paCount; i++) {
                DeviceMachineEdfa pa = DataParse.parseDevice1UBA(data);
                final DeviceDevice deviceDevice = _devSvs.getDeviceBySn(pa.getDiskSn());
                final DeviceDevice paDevice = insertOrUpdateNMSSon(pa.getDiskSn(), DiskTypeEnum.EDFA.name(), nms);
                pa.setDeviceId(deviceDevice.getDeviceId());
                _edfaService.save(pa);
                _msp2000AlarmProcess.edfaAlarm(pa, paDevice);
                data = data.substring(120);
            }

            for (int i = 0; i < rtCount; i++) {
                DeviceMachineRt rt = DataParse.parseDevice1URt(data);
                final DeviceDevice rtDevice = insertOrUpdateNMSSon(rt.getDiskSn(), DiskTypeEnum.RT.name(), nms);
                final DeviceDevice deviceDevice = _devSvs.getDeviceBySn(rt.getDiskSn());
                rt.setDeviceId(deviceDevice.getDeviceId());
                _rtService.save(rt);
                _msp2000AlarmProcess.rtAlarm(rt, rtDevice);
                data = data.substring(192 + 24 + 2);
            }
            for (int i = 0; i < fecCount; i++) {
                DeviceMachineFec fecData = DataParse.parseDeviceNMSFec(data);
                boolean fec16 = true;
                if (fecData.getFecModuleList() != null) {
                    if (fecData.getFecModuleList().get(0).getDescription().contains("2.5")) {
                        data = data.substring(292);
                    } else {
                        fec16 = false;
                        data = data.substring(278);
                    }
                } else {
                    data = data.substring(338);
                }
                DeviceDevice fecDevice;
                if (fec16)
                    fecDevice = insertOrUpdateNMSSon(fecData.getDiskSn(), DiskTypeEnum.FEC16.name(), nms);
                else
                    fecDevice = insertOrUpdateNMSSon(fecData.getDiskSn(), DiskTypeEnum.FEC64.name(), nms);

                final DeviceDevice deviceDevice = _devSvs.getDeviceBySn(fecData.getDiskSn());
                fecData.setDeviceId(deviceDevice.getDeviceId());
                _fecService.save(fecData);
                if (fecData.getFecModuleList() != null) {
                    fecData.getFecModuleList().forEach(item -> item.setMachineFecId(fecData.getMachineFecId()));
                }
                _fecModuleService.saveBatch(fecData.getFecModuleList());
                _msp2000AlarmProcess.fecAlarm(fecData, fecDevice);
            }

        }
    }

    /**
     * 新增或更新nms下的设备信息
     *
     * @param deviceSn 子设备sn
     * @param nms      nms 路由设备
     */
    private DeviceDevice insertOrUpdateNMSSon(String deviceSn, String deviceType, DeviceDevice nms) {
        DeviceDevice bySn = _devSvs.getDeviceBySn(deviceSn);
        if (bySn == null) {
            //insert device
            bySn = new DeviceDevice().setDeptId(nms.getDeptId()).setDeviceSn(deviceSn)
                    .setDeviceName(deviceType + "@" + deviceSn).setDeviceModel(deviceType)
                    .setDeviceType(deviceType).setParentId(nms.getDeviceId())
                    .setCreateTime(LocalDateTime.now())
                    .setDeviceDigest(Constant.EU);
            bySn.insert();
        } else if (bySn.getParentId() != nms.getDeviceId()) {
            bySn.setParentId(nms.getDeviceId());
            bySn.updateById();
        }
        return bySn;
    }
}
